package cn.gqr.config;

import cn.gqr.uitl.SessionUitl;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

//WebSecurityConfigurerAdapter  web安全配置模板
@Configuration
@EnableWebSecurity  //开启过滤器功能
public class MySecConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService uds;

    @Autowired
    ObjectMapper om;

    //认证管理器
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(uds);

    }


    //Http 请求安全处理
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 链式编程
        // 请求授权的设置
        http
            .authorizeRequests()
                .antMatchers("/","/index","/goRegister","/register").permitAll()//访问index.html不要权限验证
                .antMatchers("/api/public/**").permitAll()//访问/api/public/**不要权限验证
                .anyRequest().authenticated()//其他所有路径都需要权限校验
            .and()
                .csrf().disable()//默认开启，这里先显式关闭
            .formLogin()
                .loginPage("/login")
                .loginProcessingUrl("/doLogin")
                .successHandler(new AuthenticationSuccessHandler() {
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest Req,
                                                        HttpServletResponse Resp,
                                                        Authentication auth) throws IOException, ServletException {
                        System.out.println("登陆成功....");
                        Resp.setContentType("application/json;charset=utf-8");
                        System.out.println("登录成功 .Authorities.... " + auth.getAuthorities());
                        String action = "/";
                        Map map = new HashMap();
                        map.put("status",200);
                        map.put("msg","登陆成功");
                        map.put("action",action);
                        String msg = om.writeValueAsString(map);
                        Resp.getWriter().write(msg);
                        Resp.getWriter().flush();
                        Resp.getWriter().close();
                    }
                })
            .and()
                .logout()//开启注销登陆
                .logoutUrl("/logout")//注销登陆请求url
                .clearAuthentication(true)//清除身份信息
                .invalidateHttpSession(true) //session失效
                .logoutSuccessHandler(new LogoutSuccessHandler() { //注销成功 处理
                    @Override
                    public void onLogoutSuccess(HttpServletRequest req,
                                                HttpServletResponse resp,
                                                Authentication auth)throws IOException {
                        resp.sendRedirect("/index"); //跳转到自定义首页

                    }
                });

    }

    //*代表当前文件夹
    //**包括子文件夹
    //静态资源放行
    @Override
    public void configure(WebSecurity web) throws Exception {
        //解决静态资源被拦截的问题
        web.ignoring().antMatchers("/css/**");
        web.ignoring().antMatchers("/js/**");
        web.ignoring().antMatchers("/img/**");
        web.ignoring().antMatchers("/login/**");
        //解决服务注册url被拦截的问题
        web.ignoring().antMatchers("/resources/**");
    }

    //密码比对方式
    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

}
